package com.example.ecommercemarketing.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.*;

/**
 * 线程池管理器
 */
@Component
@Slf4j
public class ThreadPoolManager implements DisposableBean {
    @Autowired
    @Qualifier("marketingThreadPool")
    protected ThreadPoolExecutor marketingThreadPool;

    @Resource(name = "productCenterThreadPoolTtl")
    protected ExecutorService productCenterThreadPoolTtl;

    @Value("${thread-pool.shutdown.timeout:10}")
    private int shutdownTimeoutSeconds;


    @Override
    public void destroy() {
        shutdownThreadPool(); // Spring 销毁时关闭
    }

    /**
     * 关闭线程池
     */
    private void shutdownThreadPool() {
        shutdownOneThreadPoolCatchException(marketingThreadPool, "marketingThreadPool");
        shutdownOneThreadPoolCatchException(productCenterThreadPoolTtl, "productCenterThreadPoolTtl");
    }

    /**
     * 关闭1个线程池，捕获异常
     *
     * @param executorService 要关闭的线程池
     * @param logMark         日志标记，仅用于记录在日志中，用于区分日志
     */
    private void shutdownOneThreadPoolCatchException(ExecutorService executorService, Object logMark) {
        try {
            shutdownOneThreadPool(executorService, logMark);
        } catch (Exception e) {
            log.error("cjie,shutdownOneThreadPoolCatchException,exception occurs!{}", logMark, e);
        }
    }

    /**
     * 关闭1个线程池
     *
     * @param executorService 要关闭的线程池
     * @param logMark         日志标记，仅用于记录在日志中，用于区分日志
     */
    private void shutdownOneThreadPool(ExecutorService executorService, Object logMark) {
        if (executorService == null) {
            log.warn("cjie,shutdownOneThreadPool,executorService is null!");
            return;
        }

        if (executorService.isShutdown()) {
            log.warn("cjie,shutdownOneThreadPool,executorService is already shutdown, no need to shutdown again!{}", logMark);
            return;
        }

        log.info("cjie,Shutting down thread pool...{}", logMark);
        executorService.shutdown(); // 1. 停止接收新任务
        try {
            // 2. 等待一会儿（默认10秒）
            if (!executorService.awaitTermination(this.shutdownTimeoutSeconds, TimeUnit.SECONDS)) {
                List<Runnable> skippedTasks = executorService.shutdownNow(); // 3. 强制终止
                log.info("cjie,强制关闭，跳过任务: {}", skippedTasks.size());
            }
        } catch (InterruptedException e) {
            log.error("cjie,强制关闭线程池时发生InterruptedException!", e);
            executorService.shutdownNow();
            Thread.currentThread().interrupt(); // 恢复中断状态
        }

        log.info("cjie,Thread pool shutdown complete.{}", logMark);
    }

    /**
     * 注册 JVM 钩子（双重保障）
     */
    @PostConstruct
    public void init() {
        log.info("cjie,Registering JVM shutdown hook...");
        Runtime.getRuntime().addShutdownHook(new Thread(this::shutdownThreadPool));
        log.info("cjie,JVM shutdown hook registered.");
    }

}
